package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.HttpClientUtil;
import cn.com.acca.ma.common.util.ModelConverter;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.constant.FilterMethod;
import cn.com.acca.ma.constant.StockInfoMark;
import cn.com.acca.ma.model.*;
import cn.com.acca.ma.pojo.*;
import cn.com.acca.ma.service.Real4StockTransactionRecordService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Real4StockTransactionRecordServiceImpl extends BaseServiceImpl<Real4StockTransactionRecordServiceImpl, Real4StockTransactionRecord> implements
        Real4StockTransactionRecordService {

    /**
     * 实时地判断买卖条件，给出交易建议，并保存在文件中
     */
    @Override
    public void realTimeJudgeConditionAndGiveSuggestion() {
        logger.info("开始实时地判断买卖条件，给出交易建议，并保存在文件中");

        // 买卖建议字符串
        StringBuffer printRealBuySellSuggestion = new StringBuffer();

        // 参数
        String weekBeginDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.week.beginDate");
        String lastDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.pre.calculate.transaction.condition.date");
        String date = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.realtime.judge.condition.give.suggestion.date");
        boolean historyDataJudge = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.history.data.judge.condition.give.suggestion"));
        Integer mandatoryStopLoss = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.mandatoryStopLoss"));
        Double mandatoryStopLossRate = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.mandatoryStopLossRate"));
        Integer mandatoryStopProfit = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.mandatoryStopProfit"));
        Double mandatoryStopProfitRate = Double.parseDouble(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.mandatoryStopProfitRate"));
        String xrBeginDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.xr.begin.date");
        String highestLowestPriceBeginDate = PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.current.closePrice.compareTo.someTime.highest.lowest.price.begin.date");
        Integer currentClosePriceCompareToSomeTimeHighestPrice = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.current.closePrice.compareTo.someTime.highest.price"));
        Integer currentClosePriceCompareToSomeTimeLowestPrice = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.current.closePrice.compareTo.someTime.lowest.price"));
        Integer closePriceStart = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.closePrice.start"));
        Integer closePriceEnd = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.closePrice.end"));
        Integer oneStockTransactionCapitalAmount = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.one.stock.transaction.capital.amount"));
        Boolean useMinFilterConditionWhenBuy = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.useMinFilterConditionWhenBuy"));
        Boolean useMinFilterConditionWhenSell = Boolean.parseBoolean(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.useMinFilterConditionWhenSell"));
        Integer shippingSpaceControl = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.shippingSpaceControl"));
        Integer shippingSpace = Integer.parseInt(PropertiesUtil.getValue(MODEL_FILTER_PROPERTIES, "filter.real4.transaction.shippingSpace"));

        // 现在的仓位
        Integer holdStockNumber = real4AccountDao.findAll().get(0).getHoldStockNumber();
        // 本周的开始时间和结束时间
        WeekDate weekDate = weekDateDao.findByDateBetween(DateUtil.stringToDate(date));

        /*********************************** 卖股票/还券的建议 *********************************/
        BullStockSuggestionList bullStockSuggestionList = new BullStockSuggestionList();
        ShortStockSuggestionList shortStockSuggestionList = new ShortStockSuggestionList();
        // 之前买入，现在还没有卖出的股票：查找real4_stock_transaction_record表中，sell_date、sell_price、sell_amount列都为空的记录
        List<StockInfoPojo> shouldSellBullStockList = new ArrayList<>();
        List<Real4StockTransactionRecord> holdBullStockNumberList = real4StockTransactionRecordDao.findBySellDateNullAndSellPriceNullAndSellAmountNull();
        for (int i = 0; i < holdBullStockNumberList.size(); i++) {
            Real4StockTransactionRecord real4StockTransactionRecord = holdBullStockNumberList.get(i);
            StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(real4StockTransactionRecord.getStockCode());

            // 开盘价，最新价，最高价，最低价
            BigDecimal newestOpenPrice = null;
            BigDecimal newestClosePrice = null;
            BigDecimal newestHighestPrice = null;
            BigDecimal newestLowestPrice = null;
            if (!historyDataJudge) {
                // 调用接口，获取股票的实时价格（只能是当天，或上一个交易日的）
                // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                if (null == stockInfo) {
                    logger.warn("股票【" + real4StockTransactionRecord.getStockCode() + "】在表stock_info中没有记录");
                    continue;
                }
                String content = null;
                try {
                    content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam().replace(".", ""));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
                JSONObject jsonObject = JSONObject.parseObject(content);
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                JSONObject param = jsonArray.getJSONObject(0);
                if (null == param.getDouble("open") || null == param.getDouble("current")
                        || null == param.getDouble("high") || null == param.getDouble("low")) {
                    logger.warn("调用接口后，没有股票【" + stockInfo.getCode() + "】，跳过");
                    continue;
                }
                newestOpenPrice = new BigDecimal(param.getDouble("open"));
                newestClosePrice = new BigDecimal(param.getDouble("current"));
                newestHighestPrice = new BigDecimal(param.getDouble("high"));
                newestLowestPrice = new BigDecimal(param.getDouble("low"));
            } else {
                if (real4StockTransactionRecord.getStockCode().equals("600861")) {
                    int x = 0;
                }
                // 从数据库中获取股票的历史交易价格（可以是之前的任意一天）
                StockTransactionDataAll tempStockTransactionDataAll = stockTransactionDataDao.findByCodeAndDate(stockInfo.getUrlParam().substring(3), DateUtil.stringToDate(date));
                if (null == tempStockTransactionDataAll) {
                    logger.warn("股票【" + stockInfo.getCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                    continue;
                }
                newestOpenPrice = tempStockTransactionDataAll.getOpenPrice();
                newestClosePrice = tempStockTransactionDataAll.getClosePrice();
                newestHighestPrice = tempStockTransactionDataAll.getHighestPrice();
                newestLowestPrice = tempStockTransactionDataAll.getLowestPrice();
            }

            Real4TransactionCondition real4TransactionCondition = real4TransactionConditionDao.findByStockCode(real4StockTransactionRecord.getStockCode());

//            if (real4TransactionCondition.getStockCode().equals("601816")) {
//                int bug = 0;
//            }

            // 强制止盈
            if (mandatoryStopProfit == 1) {
                // 之前是做多的
                if (real4StockTransactionRecord.getFilterType().intValue() % 2 == 1) {
                    BigDecimal profit = newestClosePrice.subtract(real4StockTransactionRecord.getBuyPrice()).divide(real4StockTransactionRecord.getBuyPrice(), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                    if (profit.compareTo(BigDecimal.valueOf(mandatoryStopProfitRate)) >= 0) {
                        logger.info("股票【" + real4StockTransactionRecord.getStockCode() + "】的收益率是【" + profit +
                                "】，超过了阈值【" + mandatoryStopProfitRate + "】，卖出");
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setFilterType(FilterMethod.MANDATORY_STOP_PROFIT);
                        shouldSellBullStockList.add(stockInfoPojo);
                        holdStockNumber--;
                        continue;
                    }
                }
            }

            // 强制止损
            if (mandatoryStopLoss == 1) {
                // 之前是做多的
                if (real4StockTransactionRecord.getFilterType().intValue() % 2 == 1) {
                    BigDecimal loss = newestClosePrice.subtract(real4StockTransactionRecord.getBuyPrice()).divide(real4StockTransactionRecord.getBuyPrice(), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(-100));
                    if (loss.compareTo(BigDecimal.valueOf(mandatoryStopLossRate)) >= 0) {
                        logger.info("股票【" + real4StockTransactionRecord.getStockCode() + "】的损失率是【" + loss +
                                "】，超过了阈值【" + mandatoryStopLossRate + "】，卖出");
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setFilterType(FilterMethod.MANDATORY_STOP_LOSS);
                        shouldSellBullStockList.add(stockInfoPojo);
                        holdStockNumber--;
                        continue;
                    }
                }
            }

            // 判断是否macd死叉
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.MACD_GOLD_CROSS)
                    && null != real4TransactionCondition.getMacdDeadCrossClosePrice()
                    && newestClosePrice.compareTo(real4TransactionCondition.getMacdDeadCrossClosePrice()) <= 0) {
                StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                stockInfoPojo.setFilterType(FilterMethod.MACD_DEAD_CROSS);
                shouldSellBullStockList.add(stockInfoPojo);
                holdStockNumber--;
                continue;
            }
            // 判断是否close_price死叉ma5
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.CLOSE_PRICE_GOLD_CROSS_MA)
                    && null != real4TransactionCondition.getCPMa5DCClosePrice()
                    && newestClosePrice.compareTo(real4TransactionCondition.getCPMa5DCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 4, BigDecimal.ROUND_HALF_UP)) <= 0) {
                StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                stockInfoPojo.setFilterType(FilterMethod.CLOSE_PRICE_DEAD_CROSS_MA);
                shouldSellBullStockList.add(stockInfoPojo);
                holdStockNumber--;
                continue;
            }
            // 判断是否hei_kin_ashi下跌趋势
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.HEI_KIN_ASHI_UP_DOWN)
                    && null != real4TransactionCondition.getHKADownHKAOpenPrice()) {
                BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 4, BigDecimal.ROUND_HALF_UP);
                Date previousDate = stockTransactionDataDao.findPreviousDateByDate(false, date);
                StockTransactionData preStockTransactionData = stockTransactionDataDao.findLastByCodeAndDate(real4TransactionCondition.getStockCode(), previousDate);
                BigDecimal heiKinAshiOpenPrice = null;
                if (null == preStockTransactionData) {
                    heiKinAshiOpenPrice = newestOpenPrice.add(newestClosePrice).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                } else {
                    heiKinAshiOpenPrice = preStockTransactionData.getHaOpenPrice().add(preStockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                }
                if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) < 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                    stockInfoPojo.setFilterType(FilterMethod.HEI_KIN_ASHI_DOWN_UP);
                    shouldSellBullStockList.add(stockInfoPojo);
                    holdStockNumber--;
                    continue;
                }
            }
            // 判断是否kd死叉
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.KD_GOLD_CROSS)
                    && null != real4TransactionCondition.getKdDeadCrossRsv()) {
                Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                Object[] d = (Object[]) object;
                BigDecimal highestPrice = (BigDecimal) d[0];
                BigDecimal lowestPrice = (BigDecimal) d[1];
                if (highestPrice.compareTo(newestHighestPrice) == -1) {
                    highestPrice = newestHighestPrice;
                }
                if (lowestPrice.compareTo(newestLowestPrice) == 1) {
                    lowestPrice = newestLowestPrice;
                }
                BigDecimal closePrice = real4TransactionCondition.getKdDeadCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                if (newestClosePrice.compareTo(closePrice) <= 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                    stockInfoPojo.setFilterType(FilterMethod.KD_DEAD_CROSS);
                    shouldSellBullStockList.add(stockInfoPojo);
                    holdStockNumber--;
                    continue;
                }
            }
        }
        bullStockSuggestionList.setShouldSellBullStockList(shouldSellBullStockList);
        // 之前融券，现在还没有还券的股票：查找real4_stock_transaction_record表中，buy_date、buy_price、buy_amount列都为空的记录
        List<StockInfoPojo> shouldBuyShortStockList = new ArrayList<>();
        List<Real4StockTransactionRecord> holdShortStockNumberList = real4StockTransactionRecordDao.findByBuyDateNullAndBuyPriceNullAndBuyAmountNull();
        for (int i = 0; i < holdShortStockNumberList.size(); i++) {
            Real4StockTransactionRecord real4StockTransactionRecord = holdShortStockNumberList.get(i);
            StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(real4StockTransactionRecord.getStockCode());

            // 开盘价，最新价，最高价，最低价
            BigDecimal newestOpenPrice = null;
            BigDecimal newestClosePrice = null;
            BigDecimal newestHighestPrice = null;
            BigDecimal newestLowestPrice = null;
            if (!historyDataJudge) {
                // 调用接口，获取股票的实时价格（只能是当天，或上一个交易日的）
                // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                if (null == stockInfo) {
                    logger.warn("调用接口后，股票【" + real4StockTransactionRecord.getStockCode() + "】在表stock_info中没有记录");
                    continue;
                }
                String content = null;
                try {
                    content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam().replace(".", ""));
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
                JSONObject jsonObject = JSONObject.parseObject(content);
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                if (jsonArray.size() == 0) {
                    continue;
                }
                JSONObject param = jsonArray.getJSONObject(0);
                if (null == param.getDouble("open") || null == param.getDouble("current")
                        || null == param.getDouble("high") || null == param.getDouble("low")) {
                    logger.warn("调用接口后，没有股票【" + stockInfo.getCode() + "】，跳过");
                    continue;
                }
                newestOpenPrice = new BigDecimal(param.getDouble("open"));
                newestClosePrice = new BigDecimal(param.getDouble("current"));
                newestHighestPrice = new BigDecimal(param.getDouble("high"));
                newestLowestPrice = new BigDecimal(param.getDouble("low"));
            } else {
                // 从数据库中获取股票的历史交易价格（可以是之前的任意一天）
                StockTransactionDataAll tempStockTransactionDataAll = stockTransactionDataDao.findByCodeAndDate(stockInfo.getUrlParam().substring(3), DateUtil.stringToDate(date));
                if (null == tempStockTransactionDataAll) {
                    logger.warn("股票【" + stockInfo.getCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                    continue;
                }
                newestOpenPrice = tempStockTransactionDataAll.getOpenPrice();
                newestClosePrice = tempStockTransactionDataAll.getClosePrice();
                newestHighestPrice = tempStockTransactionDataAll.getHighestPrice();
                newestLowestPrice = tempStockTransactionDataAll.getLowestPrice();
            }

//            if (real4StockTransactionRecord.getStockCode().equals("601816") ) {
//                int x = 0;
//            }

            Real4TransactionCondition real4TransactionCondition = real4TransactionConditionDao.findByStockCode(real4StockTransactionRecord.getStockCode());

            // 强制止盈
            if (mandatoryStopProfit == 1) {
                // 之前是做空的
                if (real4StockTransactionRecord.getFilterType().intValue() % 2 == 0) {
                    BigDecimal profit = newestClosePrice.subtract(real4StockTransactionRecord.getSellPrice()).divide(real4StockTransactionRecord.getSellPrice(), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(-100));
                    if (profit.compareTo(BigDecimal.valueOf(mandatoryStopProfitRate)) >= 0) {
                        logger.info("股票【" + real4StockTransactionRecord.getStockCode() + "】的收益率是【" + profit +
                                "】，超过了阈值【" + mandatoryStopProfitRate + "】，卖出");
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setFilterType(FilterMethod.MANDATORY_STOP_PROFIT);
                        shouldBuyShortStockList.add(stockInfoPojo);
                        holdStockNumber--;
                        continue;
                    }
                }
            }

            // 强制止损
            if (mandatoryStopLoss == 1) {
                // 之前是做空的
                if (real4StockTransactionRecord.getFilterType().intValue() % 2 == 0) {
                    BigDecimal loss = newestClosePrice.subtract(real4StockTransactionRecord.getSellPrice()).divide(real4StockTransactionRecord.getSellPrice(), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                    if (loss.compareTo(BigDecimal.valueOf(mandatoryStopLossRate)) >= 0) {
                        logger.info("股票【" + real4StockTransactionRecord.getStockCode() + "】的损失率是【" + loss +
                                "】，超过了阈值【" + mandatoryStopLossRate + "】，卖出");
                        StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                        stockInfoPojo.setFilterType(FilterMethod.MANDATORY_STOP_LOSS);
                        shouldBuyShortStockList.add(stockInfoPojo);
                        holdStockNumber--;
                        continue;
                    }
                }
            }

            // 判断是否macd金叉
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.MACD_DEAD_CROSS)
                    && null != real4TransactionCondition.getMacdGoldCrossClosePrice()
                    && newestClosePrice.compareTo(real4TransactionCondition.getMacdGoldCrossClosePrice()) >= 0) {
                StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                stockInfoPojo.setFilterType(FilterMethod.MACD_GOLD_CROSS);
                shouldBuyShortStockList.add(stockInfoPojo);
                holdStockNumber--;
                continue;
            }
            // 判断是否close_price金叉ma5
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.CLOSE_PRICE_DEAD_CROSS_MA)
                    && null != real4TransactionCondition.getCPMa5GCClosePrice()
                    // 改过了，原来是divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)，如果不这样，2.43就不能大于等于2.432了。
                    && newestClosePrice.compareTo(real4TransactionCondition.getCPMa5GCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) >= 0) {
                StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                stockInfoPojo.setFilterType(FilterMethod.CLOSE_PRICE_GOLD_CROSS_MA);
                shouldBuyShortStockList.add(stockInfoPojo);
                holdStockNumber--;
                continue;
            }
            // 判断是否hei_kin_ashi上涨趋势
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.HEI_KIN_ASHI_DOWN_UP)
                    && null != real4TransactionCondition.getHKAUpHKAOpenPrice()) {
                BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 4, BigDecimal.ROUND_HALF_UP);
                Date previousDate = stockTransactionDataDao.findPreviousDateByDate(false, date);
                StockTransactionData preStockTransactionData = stockTransactionDataDao.findLastByCodeAndDate(real4TransactionCondition.getStockCode(), previousDate);
                BigDecimal heiKinAshiOpenPrice = null;
                if (null == preStockTransactionData) {
                    heiKinAshiOpenPrice = newestOpenPrice.add(newestClosePrice).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                } else {
                    heiKinAshiOpenPrice = preStockTransactionData.getHaOpenPrice().add(preStockTransactionData.getHaClosePrice()).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                }
                if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) > 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                    stockInfoPojo.setFilterType(FilterMethod.HEI_KIN_ASHI_UP_DOWN);
                    shouldBuyShortStockList.add(stockInfoPojo);
                    holdStockNumber--;
                    continue;
                }
            }
            // 判断是否kd金叉
            if (null != real4TransactionCondition
                    && real4StockTransactionRecord.getFilterType().equals(FilterMethod.KD_DEAD_CROSS)
                    && null != real4TransactionCondition.getKdGoldCrossRsv()) {
                Object object = stockTransactionDataDao.findHighestAndLowestClosePriceByCodeAndDateInEightDay(stockInfo.getCode(), DateUtil.stringToDate(date));
                Object[] d = (Object[]) object;
                BigDecimal highestPrice = (BigDecimal) d[0];
                BigDecimal lowestPrice = (BigDecimal) d[1];
                if (highestPrice.compareTo(newestHighestPrice) == -1) {
                    highestPrice = newestHighestPrice;
                }
                if (lowestPrice.compareTo(newestLowestPrice) == 1) {
                    lowestPrice = newestLowestPrice;
                }
                // 修改过，计算时保留4位小数：divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP)。// 最后只取小数点后两位：.setScale(2,BigDecimal.ROUND_DOWN)
                BigDecimal closePrice = real4TransactionCondition.getKdGoldCrossRsv().divide(new BigDecimal(100), 4, BigDecimal.ROUND_HALF_UP).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);//.setScale(2,BigDecimal.ROUND_DOWN);
                if (newestClosePrice.compareTo(closePrice) >= 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.stockInfoToStockInfoPojo(stockInfo);
                    stockInfoPojo.setFilterType(FilterMethod.KD_GOLD_CROSS);
                    shouldBuyShortStockList.add(stockInfoPojo);
                    holdStockNumber--;
                    continue;
                }
            }
        }
        shortStockSuggestionList.setShouldBuyShortStockList(shouldBuyShortStockList);

        /*********************************** 买股票/融券的建议 *********************************/
        List<StockInfoPojo> shouldBuyBullStockList = new ArrayList<>();
        List<StockInfoPojo> shouldSellShortStockList = new ArrayList<>();
        List<StockInfoPojo> macdGoldCrossShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> macdDeadCrossShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> closePriceGoldCrossMa5ShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> closePriceDeadCrossMa5ShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> heiKinAshiUpDownShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> heiKinAshiDownUpShouldSellStockList = new ArrayList<>();
        List<StockInfoPojo> kdGoldCrossShouldBuyStockList = new ArrayList<>();
        List<StockInfoPojo> kdDeadCrossShouldSellStockList = new ArrayList<>();

//        BigDecimal newestOpenPrice = null;
//        BigDecimal newestClosePrice = null;
//        BigDecimal newestHighestPrice = null;
//        BigDecimal newestLowestPrice = null;
        // 如果是实时交易，需要临时计算数据
        if (!historyDataJudge) {
            // 如果是从网上获取数据，则先删除stock_transaction_data表和stock_transaction_data_all表中，当天的记录
            stockTransactionDataDao.deleteStockTransactionDataByDate(date, date);
            stockTransactionDataAllDao.deleteWithDate(date, date);
            // 删除stock_week表中这一周的记录
            stockWeekDao.deleteByBeginDateAndEndDate(weekDate.getBeginDate(), weekDate.getEndDate());

            List<StockInfo> stockInfoList = stockInfoDao.getAllStockInfo();
            if (null != stockInfoList && stockInfoList.size() > 0) {
                for (int i = 0; i < stockInfoList.size(); i++) {
                    StockInfo stockInfo = stockInfoList.get(i);
                    if (!historyDataJudge) {
                        // 调用接口，获取股票的实时价格（只能是当天，或上一个交易日的）
                        String content = null;
                        try {
                            content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + stockInfo.getUrlParam().replace(".", ""));
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (URISyntaxException e) {
                            e.printStackTrace();
                        }
                        JSONObject jsonObject = JSONObject.parseObject(content);
                        JSONArray jsonArray = jsonObject.getJSONArray("data");
                        if (jsonArray.size() == 0) {
                            continue;
                        }
                        JSONObject param = jsonArray.getJSONObject(0);
                        if (null == param.getDouble("open") || null == param.getDouble("current")
                                || null == param.getDouble("high") || null == param.getDouble("low")) {
                            logger.warn("调用接口后，没有股票【" + stockInfo.getCode() + "】，跳过");
                            continue;
                        }
                        // 开盘价，最新价，最高价，最低价
                        BigDecimal newestOpenPrice = new BigDecimal(param.getDouble("open"));
                        BigDecimal newestClosePrice = new BigDecimal(param.getDouble("current"));
                        BigDecimal newestHighestPrice = new BigDecimal(param.getDouble("high"));
                        BigDecimal newestLowestPrice = new BigDecimal(param.getDouble("low"));
                        StockTransactionData stockTransactionData = new StockTransactionData();
                        stockTransactionData.setCode(stockInfo.getCode());
                        stockTransactionData.setDate(DateUtil.stringToDate(date));
                        stockTransactionData.setOpenPrice(newestOpenPrice);
                        stockTransactionData.setClosePrice(newestClosePrice);
                        stockTransactionData.setHighestPrice(newestHighestPrice);
                        stockTransactionData.setLowestPrice(newestLowestPrice);
                        stockTransactionDataDao.save(stockTransactionData);
                    }
                }
                // 如果是从网上获取数据，则存储在stock_transaction_data_all表中
                stockTransactionDataAllDao.writeStockTransactionDataAllByDate(false, date, date);
                // 计算stock_week表中的记录
                stockWeekDao.writeStockWeekByDate(weekBeginDate, date);
                stockWeekDao.writeStockWeekMAByDate(weekBeginDate, date);
            }
        }

        /*********************************** 现在的仓位，使用哪种算法 *********************************/
        // 判断上个星期是金叉状态，还是死叉状态
        Boolean goldCross = false;
        Boolean deadCross = false;
        StockWeekAverageClosePriceAndMa5 lastFirstStockWeekAverageClosePrice;
        StockWeekAverageClosePriceAndMa5 lastSecondStockWeekAverageMa5 = null;
        // 上周和上上周的平均close_price和ma5
//        List<StockWeekAverageClosePriceAndMa5> stockWeekAverageClosePriceAndMa5List = stockWeekDao.findLastTwoStockWeekAverageClosePriceAndMA5ByDateOrderByBeginDateAsc(date);
        // 本周和上周的平均close_price和ma5
        List<StockWeekAverageClosePriceAndMa5> stockWeekAverageClosePriceAndMa5List = stockWeekDao.findThisTwoStockWeekAverageClosePriceAndMA5ByDateOrderByBeginDateAsc(date);
        if (null != stockWeekAverageClosePriceAndMa5List && stockWeekAverageClosePriceAndMa5List.size() == 2) {
            lastFirstStockWeekAverageClosePrice = stockWeekAverageClosePriceAndMa5List.get(0);
            lastSecondStockWeekAverageMa5 = stockWeekAverageClosePriceAndMa5List.get(1);

            // 如果上个星期是金叉状态，则考虑接下来的处理
            if (lastFirstStockWeekAverageClosePrice.getAverageClosePrice().doubleValue() >= lastFirstStockWeekAverageClosePrice.getAverageMA5().doubleValue()
                /*&& lastSecondStockWeekAverageKD.getAverageK().doubleValue() <= lastSecondStockWeekAverageKD.getAverageD().doubleValue()*/) {
                goldCross = true;
                logger.info("上个星期是金叉状态");
            }

            // 如果上个星期是死叉状态，则考虑接下来的处理
            if (lastFirstStockWeekAverageClosePrice.getAverageClosePrice().doubleValue() <= lastFirstStockWeekAverageClosePrice.getAverageMA5().doubleValue()
                /*&& lastSecondStockWeekAverageKD.getAverageK().doubleValue() >= lastSecondStockWeekAverageKD.getAverageD().doubleValue()*/) {
                deadCross = true;
                logger.info("上个星期是死叉状态");
            }
        } else {
            logger.warn("没有前两个星期的记录或者不足两个星期，无法继续执行");

            return;
        }

        // 用于实时计算仓位，以防股票数量超过仓位数量
        Integer countShippingSpace = shippingSpace;
        // 判断做多/做空时，是使用所有过滤条件，还是使用最少的过滤条件
        boolean allFilterCondition = true;
        if (useMinFilterConditionWhenSell) {
            allFilterCondition = false;
        }
        if (useMinFilterConditionWhenBuy) {
            allFilterCondition = false;
        }
        List<Real4TransactionConditionPojo> real4TransactionConditionPojoList = real4TransactionConditionDao.findByConditionForReal4TransactionConditionPojo(allFilterCondition, date);
        if (null != real4TransactionConditionPojoList && real4TransactionConditionPojoList.size() > 0) {
            for (int i = 0; i < real4TransactionConditionPojoList.size(); i++) {
                Real4TransactionConditionPojo real4TransactionConditionPojo = real4TransactionConditionPojoList.get(i);

//                if (real4TransactionConditionPojo.getStockCode().equals("601916") || real4TransactionConditionPojo.getStockCode().equals("601988")
//                        || real4TransactionConditionPojo.getStockCode().equals("601138")) {
//                    int pause = 0;
//                }

                // 开盘价，最新价，最高价，最低价
                BigDecimal newestOpenPrice = null;
                BigDecimal newestClosePrice = null;
                BigDecimal newestHighestPrice = null;
                BigDecimal newestLowestPrice = null;
                if (!historyDataJudge) {
                    // 调用接口，获取股票的实时价格（只能是当天，或上一个交易日的）
                    // 像股票代码为510300（ETF300）这种股票在stock_info表中没有，此处只能continue
                    if (null == real4TransactionConditionPojo) {
                        logger.warn("股票【" + real4TransactionConditionPojo.getStockCode() + "】在表stock_info中没有记录");
                        continue;
                    }
                    String content = null;
                    try {
                        content = HttpClientUtil.get(HQ_SINAJS_URL_PREFIX + real4TransactionConditionPojo.getUrlParam().replace(".", ""));
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (URISyntaxException e) {
                        e.printStackTrace();
                    }
                    JSONObject jsonObject = JSONObject.parseObject(content);
                    JSONArray jsonArray = jsonObject.getJSONArray("data");
                    JSONObject param = jsonArray.getJSONObject(0);
                    if (null == param.getDouble("open") || null == param.getDouble("current")
                            || null == param.getDouble("high") || null == param.getDouble("low")) {
                        logger.warn("调用接口后，没有股票【" + real4TransactionConditionPojo.getStockCode() + "】，跳过");
                        continue;
                    }
                    newestOpenPrice = new BigDecimal(param.getDouble("open"));
                    newestClosePrice = new BigDecimal(param.getDouble("current"));
                    newestHighestPrice = new BigDecimal(param.getDouble("high"));
                    newestLowestPrice = new BigDecimal(param.getDouble("low"));
                } else {
                    if (real4TransactionConditionPojo.getStockCode().equals("601865") || real4TransactionConditionPojo.getStockCode().equals("601686")) {
                        int x = 0;
                    }
                    // 从数据库中获取股票的历史交易价格（可以是之前的任意一天）
                    if (null == real4TransactionConditionPojo) {
                        logger.warn("股票【" + real4TransactionConditionPojo.getStockCode() + "】，日期【" + date + "】在表stock_transaction_data_all中没有记录");
                        continue;
                    }
                    newestOpenPrice = real4TransactionConditionPojo.getOpenPriceFromDB();
                    newestClosePrice = real4TransactionConditionPojo.getClosePriceFromDB();
                    newestHighestPrice = real4TransactionConditionPojo.getHighestPriceFromDB();
                    newestLowestPrice = real4TransactionConditionPojo.getLowestPriceFromDB();
                }

                // 如果当前价格不在区间之内，则跳过
                if (newestClosePrice.doubleValue() < closePriceStart || newestClosePrice.doubleValue() > closePriceEnd) {
                    continue;
                }

                // 如果这只股票当日除权了，则跳过
                double downPercentage = newestClosePrice.subtract(real4TransactionConditionPojo.getPreviousClosePrice()).divide(real4TransactionConditionPojo.getPreviousClosePrice(), 4, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
                Date judgementDate = DateUtil.stringToDate("2020-08-24");
                if (DateUtil.stringToDate(xrBeginDate).before(judgementDate)
                        && downPercentage < -11) {
                    continue;
                }
                if ((DateUtil.stringToDate(xrBeginDate).after(judgementDate) || DateUtil.stringToDate(xrBeginDate).equals(judgementDate))
                        && real4TransactionConditionPojo.getStockCode().startsWith("300")
                        && downPercentage < -22) {
                    continue;
                }
                if ((DateUtil.stringToDate(xrBeginDate).after(judgementDate) || DateUtil.stringToDate(xrBeginDate).equals(judgementDate))
                        && !real4TransactionConditionPojo.getStockCode().startsWith("300")
                        && downPercentage < -11) {
                    continue;
                }

                if (null == real4TransactionConditionPojo.getWeekMa5() || null == real4TransactionConditionPojo.getWeekClosePrice()) {
                    logger.info("股票【" + real4TransactionConditionPojo.getStockCode() + "】在【" + real4TransactionConditionPojo.getWeekBeginDate() +
                            "】和【" + real4TransactionConditionPojo.getWeekEndDate() + "】这一周没有周线级别的交易记录，应该是停牌了");
                    continue;
                }
                if (goldCross) {
                    // 如果这只股票周线级别MA5没有金叉close_price，则跳过
                    if (real4TransactionConditionPojo.getWeekClosePrice().compareTo(real4TransactionConditionPojo.getWeekMa5()) == -1) {
                        logger.info("股票【" + real4TransactionConditionPojo.getStockCode() + "】在【" + real4TransactionConditionPojo.getWeekBeginDate()
                                + "】和【" + real4TransactionConditionPojo.getWeekEndDate() + "】这一周，MA5没有金叉close_price，不买入");
                        continue;
                    }
                }
                if (deadCross) {
                    // 如果这只股票周线级别MA5没有死叉close_price，则跳过
                    if (real4TransactionConditionPojo.getWeekClosePrice().compareTo(real4TransactionConditionPojo.getWeekMa5()) == 1) {
                        logger.info("股票【" + real4TransactionConditionPojo.getStockCode() + "】在【" + real4TransactionConditionPojo.getWeekBeginDate()
                                + "】和【" + real4TransactionConditionPojo.getWeekEndDate() + "】这一周，MA5没有死叉close_price，不融券");
                        continue;
                    }
                }

                // 要计算的是前一天的数据
                // macd金叉
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getMacdGoldCrossClosePrice()
                        && goldCross
                        && newestClosePrice.compareTo(real4TransactionConditionPojo.getMacdGoldCrossClosePrice()) >= 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                    stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                    stockInfoPojo.setFilterType(FilterMethod.MACD_GOLD_CROSS);
                    shouldBuyBullStockList.add(stockInfoPojo);
                    macdGoldCrossShouldBuyStockList.add(stockInfoPojo);
                    countShippingSpace--;
                    continue;
                }
                // macd死叉
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getMacdDeadCrossClosePrice()
                        && deadCross
                        && newestClosePrice.compareTo(real4TransactionConditionPojo.getMacdDeadCrossClosePrice()) <= 0
                        && null != real4TransactionConditionPojo.getMark()
                        && real4TransactionConditionPojo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                    StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                    stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                    stockInfoPojo.setFilterType(FilterMethod.MACD_DEAD_CROSS);
                    shouldSellShortStockList.add(stockInfoPojo);
                    macdDeadCrossShouldSellStockList.add(stockInfoPojo);
                    countShippingSpace--;
                    continue;
                }
                // close_price金叉ma5
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getCPMa5GCClosePrice()
                        && goldCross
                        && newestClosePrice.compareTo(real4TransactionConditionPojo.getCPMa5GCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 4, BigDecimal.ROUND_HALF_UP)) >= 0) {
                    StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                    stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                    stockInfoPojo.setFilterType(FilterMethod.CLOSE_PRICE_GOLD_CROSS_MA);
                    shouldBuyBullStockList.add(stockInfoPojo);
                    closePriceGoldCrossMa5ShouldBuyStockList.add(stockInfoPojo);
                    countShippingSpace--;
                    continue;
                }
                // close_price死叉ma5
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getCPMa5DCClosePrice()
                        && deadCross
                        // 此处改过，原来是divide(new BigDecimal(5), 4, BigDecimal.ROUND_HALF_UP)，现在是divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)，因此所有的移动平均线的计算都是只保留小数点后2位（四舍五入）
                        && newestClosePrice.compareTo(real4TransactionConditionPojo.getCPMa5DCClosePrice().multiply(new BigDecimal(4)).add(newestClosePrice).divide(new BigDecimal(5), 2, BigDecimal.ROUND_HALF_UP)) <= 0
                        && null != real4TransactionConditionPojo.getMark()
                        && real4TransactionConditionPojo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                    StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                    stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                    stockInfoPojo.setFilterType(FilterMethod.CLOSE_PRICE_DEAD_CROSS_MA);
                    shouldSellShortStockList.add(stockInfoPojo);
                    closePriceDeadCrossMa5ShouldSellStockList.add(stockInfoPojo);
                    countShippingSpace--;
                    continue;
                }
                // hei_kin_ashi上涨趋势
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getHKAUpHKAOpenPrice()
                        && goldCross) {
                    BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal heiKinAshiOpenPrice = real4TransactionConditionPojo.getLastHaOpenPrice().add(real4TransactionConditionPojo.getLastHaClosePrice()).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                    if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) > 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        stockInfoPojo.setFilterType(FilterMethod.HEI_KIN_ASHI_UP_DOWN);
                        shouldBuyBullStockList.add(stockInfoPojo);
                        heiKinAshiUpDownShouldBuyStockList.add(stockInfoPojo);
                        countShippingSpace--;
                        continue;
                    }
                }
                // hei_kin_ashi下跌趋势
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getHKADownHKAOpenPrice()
                        && deadCross
                        && null != real4TransactionConditionPojo.getMark()
                        && real4TransactionConditionPojo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                    BigDecimal heiKinAshiClosePrice = newestOpenPrice.add(newestClosePrice).add(newestHighestPrice).add(newestLowestPrice).divide(new BigDecimal(4), 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal heiKinAshiOpenPrice = real4TransactionConditionPojo.getLastHaOpenPrice().add(real4TransactionConditionPojo.getLastHaClosePrice()).divide(new BigDecimal(2), 4, BigDecimal.ROUND_HALF_UP);
                    if (heiKinAshiClosePrice.compareTo(heiKinAshiOpenPrice) < 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        stockInfoPojo.setFilterType(FilterMethod.HEI_KIN_ASHI_DOWN_UP);
                        shouldSellShortStockList.add(stockInfoPojo);
                        heiKinAshiDownUpShouldSellStockList.add(stockInfoPojo);
                        countShippingSpace--;
                        continue;
                    }
                }
                // kd金叉
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getKdGoldCrossRsv()
                        && goldCross) {
                    BigDecimal highestPrice = real4TransactionConditionPojo.getHighestPriceWith8Day();
                    BigDecimal lowestPrice = real4TransactionConditionPojo.getLowestPriceWith8Day();
                    if (highestPrice.compareTo(newestHighestPrice) == -1) {
                        highestPrice = newestHighestPrice;
                    }
                    if (lowestPrice.compareTo(newestLowestPrice) == 1) {
                        lowestPrice = newestLowestPrice;
                    }
                    BigDecimal closePrice = real4TransactionConditionPojo.getKdGoldCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                    if (newestClosePrice.compareTo(closePrice) >= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        stockInfoPojo.setFilterType(FilterMethod.KD_GOLD_CROSS);
                        shouldBuyBullStockList.add(stockInfoPojo);
                        kdGoldCrossShouldBuyStockList.add(stockInfoPojo);
                        countShippingSpace--;
                        continue;
                    }
                }
                // kd死叉
                if (null != real4TransactionConditionPojo
                        && null != real4TransactionConditionPojo.getKdDeadCrossRsv()
                        && deadCross
                        && null != real4TransactionConditionPojo.getMark()
                        && real4TransactionConditionPojo.getMark().equals(StockInfoMark.SECURITIES_LENDING)) {
                    BigDecimal highestPrice = real4TransactionConditionPojo.getHighestPriceWith8Day();
                    BigDecimal lowestPrice = real4TransactionConditionPojo.getLowestPriceWith8Day();
                    if (highestPrice.compareTo(newestHighestPrice) == -1) {
                        highestPrice = newestHighestPrice;
                    }
                    if (lowestPrice.compareTo(newestLowestPrice) == 1) {
                        lowestPrice = newestLowestPrice;
                    }
                    BigDecimal closePrice = real4TransactionConditionPojo.getKdDeadCrossRsv().divide(new BigDecimal(100)).multiply(highestPrice.subtract(lowestPrice)).add(lowestPrice);
                    if (newestClosePrice.compareTo(closePrice) <= 0) {
                        StockInfoPojo stockInfoPojo = ModelConverter.real4TransactionConditionPojoToStockInfoPojo(real4TransactionConditionPojo);
                        stockInfoPojo.setAmount(((int) (oneStockTransactionCapitalAmount.intValue() / newestClosePrice.doubleValue()) / 100 * 100));
                        stockInfoPojo.setFilterType(FilterMethod.KD_DEAD_CROSS);
                        shouldSellShortStockList.add(stockInfoPojo);
                        kdDeadCrossShouldSellStockList.add(stockInfoPojo);
                        countShippingSpace--;
                        continue;
                    }
                }
            }
            bullStockSuggestionList.setShouldBuyBullStockList(shouldBuyBullStockList);
            shortStockSuggestionList.setShouldSellShortStockList(shouldSellShortStockList);
        } else {
            logger.warn("没有买入股票/融券的建议");
        }

        /*********************************** 打印卖出建议和买入建议 *********************************/
        super.printlnAndCollectString(printRealBuySellSuggestion, "-------------------------------------------------------------------------");
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        // 打印应该有的仓位
        super.printlnAndCollectString(printRealBuySellSuggestion, null);

        // 打印卖出/还券股票的建议
        super.printlnAndCollectString(printRealBuySellSuggestion, "应该卖出/还券的股票：");
        if (null != bullStockSuggestionList && null != bullStockSuggestionList.getShouldSellBullStockList()
                && bullStockSuggestionList.getShouldSellBullStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : bullStockSuggestionList.getShouldSellBullStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "之前买入，现在应该卖出的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode() + "      " + FilterMethod.toDescription(stockInfoPojo.getFilterType()));
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "没有之前买入，现在应该卖出的股票的建议");
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        if (null != shortStockSuggestionList && null != shortStockSuggestionList.getShouldBuyShortStockList()
                && shortStockSuggestionList.getShouldBuyShortStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : shortStockSuggestionList.getShouldBuyShortStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "之前融券，现在应该还券的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode() + "      " + FilterMethod.toDescription(stockInfoPojo.getFilterType()));
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "没有之前融券，现在应该还券的股票的建议");
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, null);

        // 打印买入/融券股票的建议
        super.printlnAndCollectString(printRealBuySellSuggestion, "打印买入/融券股票的建议：");
        if (null != bullStockSuggestionList && null != bullStockSuggestionList.getShouldBuyBullStockList()
                && bullStockSuggestionList.getShouldBuyBullStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : bullStockSuggestionList.getShouldBuyBullStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "现在应该买入的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode() + "      " + FilterMethod.toDescription(stockInfoPojo.getFilterType()));
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "现在没有应该买入的股票的建议");
        }
        super.printlnAndCollectString(printRealBuySellSuggestion, null);
        super.printlnAndCollectString(printRealBuySellSuggestion, "应该融券的股票：");
        if (null != shortStockSuggestionList && null != shortStockSuggestionList.getShouldSellShortStockList()
                && shortStockSuggestionList.getShouldSellShortStockList().size() > 0) {
            for (StockInfoPojo stockInfoPojo : shortStockSuggestionList.getShouldSellShortStockList()) {
                super.printlnAndCollectString(printRealBuySellSuggestion, "现在应该融券的股票：" + stockInfoPojo.getName() + "      " + stockInfoPojo.getCode() + "      " + FilterMethod.toDescription(stockInfoPojo.getFilterType()));
            }
        } else {
            super.printlnAndCollectString(printRealBuySellSuggestion, "现在没有应该融券的股票的建议");
        }

        super.printlnAndCollectString(printRealBuySellSuggestion, "-------------------------------------------------------------------------");

        /*********************************** 将买卖建议保存到文件中 *********************************/
        // 保存真实交易的买卖建议
        File file;
        try {
            file = new File(PRINT_REAL_BUY_SELL_SUGGESTION);
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter writer = new FileWriter(file);
            writer.write(printRealBuySellSuggestion.toString());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("实时地判断买卖条件，给出交易建议，并保存在文件中完成");
    }

    @Override
    public String listToString(List list) {
        return null;
    }


}
